package 基础;
package 基础知识;
/*
《JVM简介》
JVM是Java Virtual Machine（Java虚拟机）的缩写，JVM是一种用于计算设备的规范，它是一个虚构出来的计算机，是通过在实际的计算机上仿真模拟各种
计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息，
使Java程序只需生成在Java虚拟机上运行的目标代码（字节码）,就可以在多种平台上不加修改地运行。JVM在执行字节码时，实际上最终还是把字节码解释成具体
平台上的机器指令执行。

JVM是JRE的一部分。它是一个虚构出来的计算机，是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构，如处理器、堆栈、寄存
器等，还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关，实现跨平台。

《JVM作用》
Java中的所有类，必须被装载到jvm中才能运行，这个装载工作是由jvm中的类装载器完成的，类装载器所做的工作实质是把类文件从硬盘读取到内存中
JVM对中央处理器（CPU）所执行的一种软件操作，用于执行编译过的Java程序码（Applet与应用程序）。

JVM就是我们常说的java虚拟机，它是整个java实现跨平台的最核心的部分，所有的java程序会首先被编译为.class的类文件，这种类文件可以在虚拟机上执行。
也就是说class并不直接与机器的操作系统相对应，而是经过虚拟机间接与操作系统交互，由虚拟机将程序解释给本地系统执行。当然只有JVM还不能成class的执行，
因为在解释class的时候JVM需要调用解释所需要的类库lib，而jre包含lib类库。
JVM屏蔽了与具体操作系统平台相关的信息，使得Java程序只需生成在Java虚拟机上运行的目标代码（字节码），就可以在多种平台上不加修改地运行。

《JVM特性》
1）移植性
无论是GC还是Hotspot都可以用在任何Java可用的地方。比方说，JRuby可以运行在其他平台上，Rails应用就可以运行在IBM主机上的JRuby上，而且这台IBM主机
运行的是CP/CMS。实际上，由于Java和OpenJDK项目的开源，我们正在看到越来越多的平台的衍生，因此JVM的移植性也将越来越棒。
2）成熟
JVM已有超过15年的历史，在过去的这些年里，许多开发者为它做出了许多贡献，使得它的性能一次又一次地提升，让JVM变得更加稳定、快速和广泛。
3）覆盖面
JRuby和JVM上的其他语言项目已经被开发者所承认，一个典型的例子是invokedynamic specification (aka JSR292)。JSR越来越配合新的语言，JVM已不
再是Java一个人定制规则。JVM正在构建成为类如JRuby等项目的优良平台。

《JVM工作原理》

JVM是java的核心和基础，在java编译器和os平台之间的虚拟处理器。它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台，可以在上面执行java的字节码程序。

─│┌┐└┘┴├┤┬┴←↓↑→╮╯╰╭
╭───────────╮                    ╭────────╮
│．java源代码 │ 　　╭──────────────→│ 类加载器 │
╰─────┬─────╯    │               ╰───┬────╯
　　　　│          │                   │
   　　↓          │　　　　　　　　　　　　 ↓
╭───────────╮    │              ╭─────────╮
│．class字节码├────╯　　　　╭───────┤字节码校验器├───────────╮      
╰───────────╯           │       ╰─────────╯           │
                        │                             │
                        ↓                             ↓
                   ╭────────╮                   ╭────────────╮
                   │　解释器  │                   │　JIT代码生成器│     
                   ╰────┬───╯                   ╰─────┬──────╯
                        │                             │
                        │                             │
                        │       ╭─────────╮           │
                        ╰──────→│　硬　　件　│←──────────╯
                                ╰─────────╯

java编译器只要面向JVM，生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序，通过JVM将每一条指令翻译成不同平台机器码，通过特定平台运行。

JVM在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机. 操作系统装入JVM是通过jdk
中Java.exe来完成,通过下面4步来完成JVM环境.

1.创建JVM装载环境和配置
首先查找jre路径，Java是通过GetApplicationHome api来获得当前的Java.exe绝对路径，c:\j2sdk1.4.2_09\bin\Java.exe,那么它会截取到绝
对路径c:\j2sdk1.4.2_09\，判断c:\j2sdk1.4.2_09\bin\Java.dll文件是否存在，如果存在就把c:\j2sdk1.4.2_09\作为jre路径，如果不存在则
判断c:\j2sdk1.4.2_09\jre\bin\Java.dll是否存在，如果存在这c:\j2sdk1.4.2_09\jre作为jre路径．如果不存在调用GetPublicJREHome
查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\“当前JRE版本号”\JavaHome的路径为jre路径。

然后装载JVM.cfg文件JRE路径+\lib+\ARCH（CPU构架）+\JVM.cfgARCH（CPU构架）的判断是通过Java_md.c中GetArch函数判断的，该函数中windows平
台只有两种情况：WIN64的‘ia64’，其他情况都为‘i386’。以我的为例：C:\j2sdk1.4.2_09\jre\lib\i386\JVM.cfg.主要的内容如下：

-client KNOWN   
-server KNOWN   
-hotspot ALIASED_TO -client   
-classic WARN   
-native ERROR   
-green ERROR  

在我们的jdk目录中jre\bin\server和jre\bin\client都有JVM.dll文件存在，而Java正是通过JVM.cfg配置文件来管理这些不同版本的JVM.dll的．通过文件我
们可以定义目前jdk中支持那些JVM,前面部分（client）是JVM名称，后面是参数，KNOWN表示JVM存在，ALIASED_TO表示给别的JVM取一个别名，WARN表示不存在时找
一个JVM替代，ERROR表示不存在抛出异常．在运行Java XXX是，Java.exe会通过CheckJVMType来检查当前的JVM类型，Java可以通过两种参数的方式来指定具体
的JVM类型，一种按照JVM.cfg文件中的JVM名称指定，第二种方法是直接指定，它们执行的方法分别是“Java -J”、“Java -XXaltJVM=”或“Java -J-XXaltJVM=”。如
果是第一种参数传递方式，CheckJVMType函数会取参数‘-J’后面的JVM名称，然后从已知的JVM配置参数中查找如果找到同名的则去掉该JVM名称前的‘-’直接返回该值；而
第二种方法，会直接返回“-XXaltJVM=”或“-J-XXaltJVM=”后面的JVM类型名称；如果在运行Java时未指定上面两种方法中的任一一种参数，CheckJVMType会取配置文
件中第一个配置中的JVM名称，去掉名称前面的‘-’返回该值。CheckJVMType函数的这个返回值会在下面的函数中汇同jre路径组合成JVM.dll的绝对路径。如果没有指定这会
使用JVM.cfg中第一个定义的JVM.可以通过set _Java_LAUNCHER_DEBUG=1在控制台上测试．
最后获得JVM.dll的路径，JRE路径+\bin+\JVM类型字符串+\JVM.dll就是JVM的文件路径了，但是如果在调用Java程序时用-XXaltJVM=参数指定的路径path,就直接
用path+\JVM.dll文件做为JVM.dll的文件路径．

2.装载JVM.dll
通过第一步已经找到了JVM的路径，Java通过LoadJavaVM来装入JVM.dll文件．装入工作很简单就是调用Windows API函数：
LoadLibrary装载JVM.dll动态连接库．然后把JVM.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变
量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。JVM.dll的装载工作宣告完成。

3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
初始化JVM，获得本地调用接口，这样就可以在Java中调用JVM的函数了．调用InvocationFunctions－>CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获
得JNIEnv结构的实例．

4.运行JAVA程序。
Java程序有两种方式一种是jar包，一种是class. 运行jar,Java -jar XXX.jar运行的时候，Java.exe调用GetMainClassName函数，该函数先获得JNIEnv实例然
后调用Java类Java.util.jar.JarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文
件：META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。之后main函数会调用Java.c中LoadClass方法装载该主类（使用JNIEnv实例的FindClass）。
main函数直接调用Java.c中LoadClass方法装载该类。如果是执行class方法。main函数直接调用Java.c中LoadClass方法装载该类。
然后main函数调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中
“public static void main(String[] args)”方法，并判断该方法是否为public方法，然后调用JNIEnv实例的CallStaticVoidMethod方法调用该Java类的main方法。


JVM执行原理
1. JVM执行顺序
1) 加载.class文件 2) 管理并分配内存 3) 执行垃圾收集
JRE（java运行时环境）由JVM构造的java程序的运行环，也是Java程序运行的环境，但是他同时一个操作系统的一个应用程序一个进程，因此他也有他自己的运行的生命周期，也有
自己的代码和数据空间。JVM在整个jdk中处于最底层，负责于操作系统的交互，用来屏蔽操作系统环境，提供一个完整的Java运行环境，因此也就虚拟计算机。操作系统装入JVM是
通过jdk中Java.exe来完成，通过下面4步来完成JVM环境：
1) 创建JVM装载环境和配置 
2) 装载JVM.dll 
3) 初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
4) 调用JNIEnv实例装载并处理class类。

2. JVM生命周期
1) JVM实例对应了一个独立运行的java程序它是进程级别 
a) 启动。启动一个Java程序时，一个JVM实例就产生了，任何一个拥有
	public static void main(String[] args)函数的class都可以作为JVM实例运行的起点 
b) 运行。main()作为该程序初始线程的起点，任何其他线程均由该线程启动。JVM内部有两种线程：守护线程和非守护线程，main()属于非守护线程，守护线程通常由JVM自己使
	用，java程序也可以表明自己创建的线程是守护线程 
c) 消亡。当程序中的所有非守护线程都终止时，JVM才退出；若安全管理器允许，程序也可以使用Runtime类或者System.exit()来退出

2) JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的

JVM原理结构


 
类装载器（ClassLoader）（用来装载.class文件）
执行引擎（执行字节码，或者执行本地方法）
运行时数据区（方法区、堆、java栈、PC寄存器、本地方法栈）
*/